package model

import (
	"cashcenter/utils/errx"
	"gorm.io/gorm/clause"
)

func QueryCashInByInId(inId string) *CashIn {
	res := CashIn{}
	GlobalDB.Where("in_id = ?", inId).First(&res)
	return &res
}
func QueryCashInsByUserId(userId int64) *[]CashIn {
	var res []CashIn
	GlobalDB.Where("user_id = ?", userId).Find(&res)
	return &res
}
func QueryCashOutsByUserId(userId int64) *[]CashOut {
	var res []CashOut
	GlobalDB.Where("user_id = ?", userId).Find(&res)
	return &res
}
func QueryCashOutByUuid(uuid string) *CashOut {
	var res CashOut
	GlobalDB.Where("out_id = ?", uuid).Find(&res)
	return &res
}

func QueryCashOutCount(stat string) (int64, error) {
	var count int64
	err := GlobalDB.Model(&CashOut{}).Where("state = ?", stat).Count(&count).Error
	return count, err
}
func QueryCashOutList(stat, isPart string, offset, num int) *[]CashOut {
	var res []CashOut
	if isPart == "0" {
		GlobalDB.Where("state = ?", stat).Order(clause.OrderByColumn{
			Column: clause.Column{
				Name: "created",
			},
			Desc: false,
		}).Find(&res)
	} else {
		GlobalDB.Where("state = ?", stat).Order(clause.OrderByColumn{
			Column: clause.Column{
				Name: "created",
			},
			Desc: false,
		}).Offset(offset).Limit(num).Find(&res)
	}
	return &res
}
func UpdateCashOut(cashOut *CashOut) error {
	return GlobalDB.Where("out_id = ?", cashOut.OutId).Updates(cashOut).Error
}

func InsertCashIn(cashIn *CashIn) error {
	return GlobalDB.Create(cashIn).Error
}
func InsertCashOut(cashOut *CashOut) error {
	return GlobalDB.Create(cashOut).Error
}

func UpdateCashIn(cashIn *CashIn) error {
	return GlobalDB.Where("in_id = ?", cashIn.InId).Updates(cashIn).Error
}

func QueryLastAccount(userId int64) *Account {
	res := Account{}
	GlobalDB.Where("user_id = ?", userId).Order(clause.OrderByColumn{
		Column: clause.Column{
			Name: "created",
		},
		Desc: true,
	}).Last(&res)
	return &res
}
func QueryAccounts(userId int64) *[]Account {
	var res []Account
	GlobalDB.Where("user_id = ?", userId).Find(&res)
	return &res
}

func InsertAccount(userId, dValue int64) (accountId int64, err error) {
	var accountLast Account

	ctx := GlobalDB.Begin()
	defer func() {
		r := recover()
		if r == nil {
			return
		}
		if err, ok := r.(error); ok {
			panic(err)
		}
	}()

	ctx.Clauses(clause.Locking{Strength: "UPDATE"}).
		Order(clause.OrderByColumn{Column: clause.Column{Name: "created"}, Desc: true}).
		Last(&accountLast, "user_id = ?", userId)
	if accountLast.Balance+dValue >= 0 {
		account := &Account{
			UserId:  userId,
			Balance: accountLast.Balance + dValue,
			DValue:  dValue,
		}
		ctx.Create(&account)
		ctx.Commit()
		return account.AccountId, nil
	}

	ctx.Rollback()
	return -1, errx.CtpError(errx.DecError)
}
